#ifndef LEX_H
#define LEX_H

#define ISTERMINAL  0
#define NOTERMINAL  1

#include "Util.h"
#include <cstdio>
#include <stdlib.h>
#include <iomanip>
#include <list>


// 词法分析
typedef enum
{
    ENDFILE, ERROR, END, RETURN, CHAR,LAMBDA,
    PROGRAM, PROCEDURE, TYPE, VAR, IF,
    THEN, ELSE, FI, WHILE, DO, ENDWH,
    BEGIN, END1, READ, WRITE, ARRAY, OF,
    RECORD, RETURN1,
    INTEGER, CHAR1, //INTEGER 是integer
    ID, INTC, CHARC,
    ASSIGN, EQ, LT, PLUS, MINUS,
    TIMES, OVER, LPAREN, RPAREN, DOT,
    COLON, SEMI, COMMA, LMIDPAREN, RMIDPAREN,
    UNDERANGE
}LexType;// 终极符

// 保留字
struct Word
{
    string str;
    LexType tok;
};

const struct Word reservedWords[21] =
{
    {"program",PROGRAM},
    {"type",TYPE},
    {"var",VAR},
    {"procedure",PROCEDURE},
    {"begin",BEGIN},
    {"end",END},
    {"array",ARRAY},
    {"of",OF},
    {"record",RECORD},
    {"if",IF},{"then",THEN},
    {"else",ELSE},
    {"fi",FI},
    {"while",WHILE},
    {"do",DO},
    {"endwh",ENDWH},
    {"read",READ},
    {"write",WRITE},
    {"return",RETURN},
    {"integer",INTEGER},
    {"char",CHAR}
};

struct Token {
    int line;
    struct Word wd;
    int index = -1; // tokenlist中的index
};// token


bool isSeparater(char ch);
bool isOperator(char ch);
bool isReserved(string ch);
bool isBlank(char ch);
bool isLetter(char ch);
bool isDigit(char ch);
bool lexicalAnalyse(FILE *fp);
struct Word getReserved(string s);
//string getString(int lexNum);
list<string> printTokenList(Token* tokenList);

string getTokenStr(LexType tkt);

#endif // LEX_H
